Function.prototype.myCall = function (context = window, ...arg) {
  if (typeof this !== "function") {
    throw new TypeError("Error");
  }
  context.fn = this;
  let res = context.fn(...arg);
  delete context.fn;
  return res;
};
Function.prototype.myApply = function (context = window, arg) {
  if (typeof this !== "function") {
    throw new TypeError("Error");
  }
  context.fn = this;
  let res = context.fn(...arg);
  delete context.fn;
  return res;
};
Function.prototype.myBind = function (context = window) {
  if (typeof this !== "function") {
    throw new TypeError("Error");
  }
  return (...arg) => this.call(context, ...arg);
};
let obj = {
  a: 1,
  b: 2,
  foo(c, d) {
    return this.a + this.b + c + d;
  },
};
let dm = {
  a: 3,
  b: 4,
};
let res = obj.foo.myCall(dm, 3, 4, 5);
console.log(res);
let res2 = obj.foo.myApply(dm, [3, 7]);
console.log(res2);
let testBind = obj.foo.myBind(dm);
let res3 = testBind(3, 7);
console.log(res3);
